package com.newly.transfer.redis;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.newly.common.base.entity.auth.TenantDetails;
import com.newly.common.base.entity.sys.api.ApiDto;
import com.newly.common.base.entity.sys.captcha.dto.CaptchaDto;
import com.newly.common.base.entity.sys.dict.po.DictPo;
import com.newly.common.base.entity.sys.menu.dto.MenuDto;
import com.newly.common.base.entity.sys.tenant.dto.SimpleTenantDto;
import com.newly.transfer.redis.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: newly-parent
 * @remark: redis传输对象
 * @author: guan
 * @create: 2021-12-20 22:58
 */
@Component
@ConditionalOnBean(RedisUtils.class)
public class RedisTransfer {

    @Autowired
    private RedisUtils redisUtils;

    private static final long TEMP_TIME = 120;

    public enum RedisSetting {
        SIMPLE_TENANT("simpleTenant:", null),
        TENANT_DETAIL("tenantDetail:", 36000),
        MENU("menuAll:", 0),
        CAPTCHA("captcha:", 5 * 60),
        API("api:", null);

        RedisSetting(String prefix, Integer time) {
            this.prefix = prefix;
            this.time = time == null ? TEMP_TIME : time;
        }

        /**
         * 前缀
         */
        private String prefix;
        /**
         * key，唯一标识
         */
        private String key;
        /**
         * 存储时长
         */
        private Long time;

        public String getKey(Object key) {
            if (!ObjectUtil.isEmpty(key)) {
                this.key = key.toString();
                return this.prefix + key.toString();
            }
            return this.prefix;
        }

        public String getPrefix() {
            return prefix;
        }

        public Long getTime() {
            return time;
        }
    }

    /**
     * @param objs
     * @return 所有数据不为空返回truue
     */
    private boolean isNotEmpty(Object... objs) {
        if (ObjectUtil.isEmpty(objs))
            return false;
        for (Object obj : objs) {
            if (obj instanceof String) {
                if (StrUtil.isBlank((String) obj)) {
                    return false;
                }
            } else {
                if (ObjectUtil.isEmpty(obj)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 存储用户详情信息
     *
     * @param username      用户名
     * @param tenantDetails 用户详情信息
     * @return 存储成功返回true
     */
    public boolean setTenantDetails(String username, TenantDetails tenantDetails) {
        if (isNotEmpty(username, tenantDetails)) {
            RedisSetting set = RedisSetting.TENANT_DETAIL;
            return redisUtils.set(set.getKey(username), tenantDetails, set.getTime());
        }
        return false;
    }

    /**
     * 获取用户详情信息
     *
     * @param username 用户名
     * @return TenantDetails.class
     */
    public TenantDetails getTenantDetails(String username) {
        if (isNotEmpty(username)) {
            RedisSetting set = RedisSetting.TENANT_DETAIL;
            if (redisUtils.hasKey(set.getKey(username))) {
                return (TenantDetails) redisUtils.get(set.getKey(username));
            }
        }
        return null;
    }

    /**
     * 清除用户详情信息
     *
     * @param username 用户名
     * @return TenantDetails.class
     */
    public boolean clearTenantDetails(String username) {
        if (isNotEmpty(username)) {
            String key = RedisSetting.TENANT_DETAIL.getKey(username);
            if (redisUtils.hasKey(key)) {
                return redisUtils.del(key);
            }
        }
        return false;
    }

    /**
     * 存储临时租户
     *
     * @param tenantId        租户id
     * @param simpleTenantDto 精简用户数据对象
     * @return 存储成功返回true
     */
    public boolean setSimpleTenant(Long tenantId, SimpleTenantDto simpleTenantDto) {
        if (isNotEmpty(simpleTenantDto)) {
            RedisSetting set = RedisSetting.SIMPLE_TENANT;
            return redisUtils.set(set.getKey(tenantId.toString()), simpleTenantDto, set.getTime());
        }
        return false;
    }

    /**
     * 获取临时租户
     *
     * @param tenantId 租户id
     * @return SimpleTenantVo.class
     */
    public SimpleTenantDto getSimpleTenant(Long tenantId) {
        RedisSetting set = RedisSetting.SIMPLE_TENANT;
        if (redisUtils.hasKey(set.getKey(tenantId))) {
            return (SimpleTenantDto) redisUtils.get(set.getKey(tenantId));
        }
        return null;
    }

    /**
     * 存储所有菜单信息
     *
     * @return 存储成功返回true
     */
    public boolean setMenus(List<MenuDto> menuDtos) {
        if (isNotEmpty(menuDtos)) {
            RedisSetting set = RedisSetting.MENU;
            return redisUtils.set(set.getKey(null), menuDtos);
        }
        return false;
    }

    /**
     * 获取所有菜单信息
     *
     * @return List MenuDto.class
     */
    public List<MenuDto> getMenus() {
        String key = RedisSetting.MENU.getKey(null);
        if (redisUtils.hasKey(key)) {
            return (List<MenuDto>) redisUtils.get(key);
        }
        return null;
    }

    /**
     * @return 清空菜单数据
     */
    public boolean clearMenus() {
        String key = RedisSetting.MENU.getKey(null);
        if (redisUtils.hasKey(key)) {
            return redisUtils.del(key);
        }
        return false;
    }

    /**
     * 缓存图形验证码
     *
     * @param captchaId  图形验证码id
     * @param captchaDto 图形验证码数据
     * @return 缓存成功返回true
     */
    public boolean setCaptcha(String captchaId, CaptchaDto captchaDto) {
        if (isNotEmpty(captchaId, captchaDto)) {
            RedisSetting set = RedisSetting.CAPTCHA;
            return redisUtils.set(set.getKey(captchaId), captchaDto, set.getTime());
        }
        return false;
    }

    /**
     * 缓存图形验证码
     *
     * @param captchaId 图形验证码id
     * @return CaptchaDto.class
     */
    public CaptchaDto getCaptcha(String captchaId) {
        if (isNotEmpty(captchaId)) {
            String key = RedisSetting.CAPTCHA.getKey(captchaId);
            if (redisUtils.hasKey(key)) {
                return (CaptchaDto) redisUtils.get(key);
            }
        }
        return null;
    }

    /**
     * 清空图形验证码
     *
     * @param captchaId 图形验证码id
     * @return 清空成功返回true
     */
    public boolean clearCaptcha(String captchaId) {
        if (isNotEmpty(captchaId)) {
            String key = RedisSetting.CAPTCHA.getKey(captchaId);
            if (redisUtils.hasKey(key)) {
                return redisUtils.del(key);
            }
        }
        return false;
    }

    /**
     * 缓存api接口
     *
     * @param serverName 服务名称
     * @param apiDto     api数据
     * @return 缓存成功返回true
     */
    public boolean addApis(String serverName, ApiDto apiDto) {
        if (isNotEmpty(apiDto)) {
            String key = RedisSetting.API.getKey(serverName);
            return redisUtils.lSet(key, apiDto);
        }
        return false;
    }

    /**
     * 缓存api接口
     *
     * @param serverName 服务名称
     * @return 缓存成功返回true
     */
    public List<ApiDto> getApis(String serverName) {
        if (isNotEmpty(serverName)) {
            String key = RedisSetting.API.getKey(serverName);
            if (redisUtils.hasKey(key)) {
                List<Object> objects = redisUtils.lGet(key, 0, -1);
                if (!ObjectUtil.isEmpty(objects)) {
                    return objects.stream().map(object -> (ApiDto) object)
                            .collect(Collectors.toList());
                }
            }
        }
        return null;
    }

    /**
     * 缓存api接口
     *
     * @param serverName 服务名称
     * @return 缓存成功返回true
     */
    public boolean clearApis(String serverName) {
        if (isNotEmpty(serverName)) {
            String key = RedisSetting.API.getKey(serverName);
            if (redisUtils.hasKey(key)) {
                return redisUtils.del(key);
            }
        }
        return false;
    }

    /**
     * 从redis中获取数据，通过泛型强转
     *
     * @param key key
     * @param t   传入的类型
     * @param <T> 类型
     * @return T.class
     */
    public <T> T get(String key, Class<T> t) {
        if (StrUtil.isBlank(key) || ObjectUtil.isEmpty(t))
            return null;
        if (redisUtils.hasKey(key)) {
            Object obj = redisUtils.get(key);
            if (!ObjectUtil.isEmpty(obj)) {
                return (T) obj;
            }
        }
        return null;
    }

    public boolean setSysDic(List<DictPo> dictPoList){
        if (!isNotEmpty(dictPoList))
            return false;
        for (DictPo dictPo : dictPoList) {
            redisUtils.set(dictPo.getCode(),dictPo.getValue());
        }
        return true;
    }

}
